/**
 * @file   GetClientMethodInfoResponsePacket.cpp
 * @author Djuro Drljaca (djurodrljaca@gmail.com)
 * @date   2013-05-30
 * @brief  DataBus Get Client Method Info Response packet.
 *
 * Copyright (C) 2013 Djuro Drljaca <djurodrljaca@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <DataBus/Common/GetClientMethodInfoResponsePacket.h>
#include <DataBus/Common/Value.h>

bool DataBus::GetClientMethodInfoResponsePacket::create(const quint8 source,
                                                        const quint8 destination,
                                                        const quint8 packetId,
                                                        const MethodInfo &methodInfo,
                                                        Packet *packet)
{
    // Check parameters
    if ((source == 0) ||
        (methodInfo.isValid() == false) ||
        (packet == 0))
    {
        // Error, invalid parameters
        return false;
    }

    // Create Header
    packet->setSource(source);
    packet->setDestination(destination);
    packet->setPacketType(PacketType_GetClientMethodInfoResponse);
    packet->setPacketId(packetId);

    // Create Payload
    QByteArray data;

    data.append(static_cast<char>(methodInfo.getId()));
    data.append(methodInfo.getName());
    data.append(static_cast<char>(methodInfo.getNoOfParameters()));
    data.append(static_cast<char>(methodInfo.getNoOfReturnValues()));

    packet->setData(data);

    // Success
    return true;
}

bool DataBus::GetClientMethodInfoResponsePacket::parse(const Packet &packet,
                                                       MethodInfo *methodInfo,
                                                       quint8 *noOfParameters,
                                                       quint8 *noOfReturnValues)
{
    // Check parameters
    if ((packet.getSource() == 0) ||
        (packet.getPacketType() != PacketType_GetClientMethodInfoResponse) ||
        (methodInfo == 0) ||
        (noOfParameters == 0) ||
        (noOfReturnValues == 0))
    {
        // Error, invalid parameters
        return false;
    }

    // Get data
    QByteArray data = packet.getData();

    if (data.size() < 4)
    {
        // Error, invalid size
        return false;
    }

    // Get Method ID
    quint8 id = static_cast<quint8>(data.at(0));

    // Get Property Name
    QString name;

    if (Value::fromBinary(data, &name, 1) == false)
    {
        // Error, failed to get Name
        return false;
    }

    int nameSize = name.toUtf8().size();

    if (nameSize > STRING_MAX_LENGTH)
    {
        // Error, name is too long
        return false;
    }

    if (data.size() != (nameSize + 4))
    {
        // Error, invalid size
        return false;
    }

    // Get No of parameters
    quint8 parameterCount = static_cast<quint8>(data.at(nameSize + 2));

    // Get No of return values
    quint8 returnValueCount = static_cast<quint8>(data.at(nameSize + 3));

    // Save values
    methodInfo->setId(id);
    methodInfo->setName(name);
    *noOfParameters = parameterCount;
    *noOfReturnValues = returnValueCount;

    // Success
    return true;
}
